#ifndef __THREAD_H__
#define __THREAD_H__
#include <ucontext.h>
typedef enum{ENDED, SLEEPING,RUNNING } thread_status;

struct thread {
	thread_status status;
	ucontext_t context;
	struct timeval* execution_time;
	int priority;
	unsigned int thread_id;
	void* retval;
	struct list* waiting;
	int valgrind_stackid;
};

void add_thread_runq(thread_t);

/* identifiant de thread */
typedef struct thread * thread_t;



/* recuperer l'identifiant du thread courant.
 */
extern thread_t thread_self(void);

/* creer un nouveau thread qui va exécuter la fonction func avec l'argument funcarg.
 * renvoie 0 en cas de succès, -1 en cas d'erreur.
 */
extern int thread_create(thread_t *newthread, void *(*func)(void *), void *funcarg);

/* passer la main à un autre thread.
 */
extern int thread_yield(void);

/* attendre la fin d'exécution d'un thread.
 * la valeur renvoyée par le thread est placée dans *retval.
 * si retval est NULL, la valeur de retour est ignorée.
 */
extern int thread_join(thread_t thread, void **retval);
/* attendre la fin d'exécution d'un thread.
 * la valeur renvoyée par le thread est placée dans *retval.
 * si retval est NULL, la valeur de retour est ignorée.
 * Contrairement à thread_join(), le thread est supprimé à la fin de cette fontion
 */
extern int final_thread_join(thread_t thread,void** retval);
/* terminer le thread courant en renvoyant la valeur de retour retval.
 * cette fonction ne retourne jamais.
 */
extern void thread_exit(void *retval) __attribute__ ((__noreturn__));

/*CES FONCTIONS SONT INTERNES A LA LIBRAIRIE*/
/*
 * Supprime un thread afin de liberer la memoire
 */
struct thread* delete_thread(struct thread * thread);
 /*
  * Ajoutent et enleve un thread en parametre
  * a la runq
  */
void add_thread_runq(thread_t thread);
void remove_thread_runq(thread_t thread);

/* Fait passer tous les threads de la liste en parametre
 * a la runq
 * retoune la nouvelle runq
 */
struct list * wake_all(struct list * src);
#endif /* __THREAD_H__ */
